﻿using System;
using System.IO;
using System.Reflection;
using System.Text;

namespace SSHTool.Util
{
    public class LogUtil
    {
        #region Instance
        private static object logLock;

        private static LogUtil _instance;

        private static string logFileName;

        private LogUtil() { }

        /// <summary>
        /// Logger instance
        /// </summary>
        public static LogUtil Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new LogUtil();
                    logLock = new object();
                    logFileName = $"{DateTime.Now.ToString("yyyy-MM-dd")}.log";
                }
                return _instance;
            }
        }
        #endregion

        public void WriteLog(object obj, LogType type = LogType.Information, bool writeDate = true, string fileName = "")
        {
            if (obj == null)
            {
                return;
            }

            WriteLog(StringUtil.ToJson(obj), type, writeDate, fileName);
        }

        /// <summary>
        /// Write log to log file
        /// </summary>
        /// <param name="logContent">Log content</param>
        /// <param name="logType">Log type</param>
        public void WriteLog(string logContent, LogType logType = LogType.Information, bool writeDate = true, string fileName = null)
        {
            try
            {
                string basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                basePath += "\\Log";
                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }

                if (string.IsNullOrEmpty(logContent))
                {
                    logContent = "";
                }

                string content = "";
                if (writeDate)
                {
                    content = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:{logType.ToString()}:{logContent}";
                }
                else
                {
                    content = logContent;
                }

                string[] logText = new string[] { content };
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = logFileName;
                }

                lock (logLock)
                {
                    File.AppendAllLines(basePath + "\\" + fileName, logText, Encoding.UTF8);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        /// <summary>
        /// Write exception to log file
        /// </summary>
        /// <param name="exception">Exception</param>
        public void Error(Exception exception)
        {
            if (exception != null)
            {
                Type exceptionType = exception.GetType();
                string text = "Exception: " + exceptionType.Name + Environment.NewLine;
                text += "               " + "Message: " + exception.Message + Environment.NewLine;
                text += "               " + "Source: " + exception.Source + Environment.NewLine;
                text += "               " + "StackTrace: " + exception.StackTrace + Environment.NewLine;
                WriteLog(text, LogType.Error);
            }
        }

        /// <summary>
        /// Write exception to log file
        /// </summary>
        /// <param name="text"></param>
        public void Error(string text)
        {
            WriteLog(text, LogType.Error);
        }

        public void Info(string text)
        {
            WriteLog(text);
        }
    }
}
